#-*- coding: UTF-8 -*-


import zlib,types
import simplejson as json

def sendData(callid,data):
    if type(data) is types.StringType:
        return sendStringData(callid,data)
    elif type(data) is types.DictType:
        return sendJsonData(callid,data)
    elif type(data) is types.IntType:
        return sendStringData(callid,str(data))
    elif type(data) is types.LongType:
        return sendStringData(callid,str(data))
    elif type(data) is types.UnicodeType:
        return sendStringData(callid,str(data.encode("UTF-8")))
    elif type(data) is types.ListType:
        return sendListData(callid,data)
    else:
        return sendError(callid,'errortype','error data type')

def sendStringData(callid,data):
    compressed = zlib.compress(data)
    size = len(compressed)+4
    lencode = protectocode(size)
    reqcode = protectocode(callid)
    return chr(0)+chr(0)+chr(0)+chr(0)+lencode+reqcode+compressed

def protectocode(size):
    lencode = ''
    if size >= 16777216 :
        lencode = lencode + chr( size / 16777216 )
        size = size % 16777216
    else:
        lencode = lencode + chr(0)
    if size >= 65536 :
        lencode = lencode + chr( size / 65536 )
        size = size % 65536
    else:
        lencode = lencode + chr(0)
    if size >= 256 :
        lencode = lencode + chr( size / 256 )
        size = size % 256
    else:
        lencode = lencode + chr(0)
    return lencode + chr(size)

def sendListData(callid,msg):
    dictid = 0
    newdict = {}
    for eele in msg:
        newdict[dictid] = eele
        dictid += 1
    return sendJsonData(callid,newdict)

def sendJsonData(callid,msg):
    #newmsg={'msucc':1,'mserverindex':MServerConfig['SERVE_INDEX']}
    #newmsg.update(msg)
    #data = json.dumps(newmsg)
    data = json.dumps(msg)
    return sendStringData(callid,data)

def sendError(callid,act,msg,disconn=False,pdata=None):
    errmsg = {}
    errmsg['msucc']=0
    errmsg['mact']=act
    errmsg['mmsg']= msg
    errmsg['mdata']= pdata
    return sendJsonData(callid,errmsg)

def is_scalar(data):
    if type(data) is types.StringType or type(data) is types.IntType or type(data) is types.LongType or type(data) is types.UnicodeType:
        return True
    return False

def _decode_list(data):
    rv = []
    for item in data:
        if isinstance(item, unicode):
            item = item.encode('utf-8')
        elif isinstance(item, list):
            item = _decode_list(item)
        elif isinstance(item, dict):
            item = _decode_dict(item)
        rv.append(item)
    return rv

def _decode_dict(data):
    rv = {}
    for key, value in data.iteritems():
        if isinstance(key, unicode):
            key = key.encode('utf-8')
        if isinstance(value, unicode):
            value = value.encode('utf-8')
        elif isinstance(value, list):
            value = _decode_list(value)
        elif isinstance(value, dict):
            value = _decode_dict(value)
        rv[key] = value
    return rv

def decodedata(buffer,recvdata):
    
    if len(buffer) < 12 :
        return True

    if buffer[0:4]!= '\x00\x00\x00\x00':
        return False

    recv_size = ord(buffer[4:5])*16777216 + ord(buffer[5:6])*65536 + ord(buffer[6:7])*256 + ord(buffer[7:8])
    recv_size += 8

    if recv_size  > len(buffer):
        return True

    if recv_size == 8 :
        print '---------------------------->protocol Error recv_size:8'
        return False

    reqId = ord(buffer[8:9])*16777216 + ord(buffer[9:10])*65536 + ord(buffer[10:11])*256 + ord(buffer[11:12])
    recv_data = buffer[12:recv_size]
    try:
        uzdata = zlib.decompress( recv_data )
    except:
        print '---------------------------->protocol Error zlib.decompress'
        print recv_size,reqId,len(buffer)
        return False
    buffer = buffer[recv_size:]
    try:
        jsondata = json.loads(uzdata,object_hook=_decode_dict)
    except:
        print '---------------------------->protocol Error'
        print recv_size,reqId,len(buffer)
        return False
    return [buffer,reqId,jsondata]
        